package com.ecarx.module_log.controller;

import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;

import com.ecarx.library_base.BaseApplication;
import com.ecarx.library_base.base_util.AppUtil;
import com.ecarx.library_base.usb.UDiskDevice;
import com.ecarx.library_base.usb.UDiskUtil;
import com.ecarx.library_base.usb.brodcast.USBReceiver;
import com.ecarx.module_log.R;
import com.ecarx.module_log.bean.FileBean;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

public class FileOutDeleteController implements USBReceiver.UsbChangeCallback {

    public static final String TAG = "FileOutDeleteController";

    private USBReceiver mUsbReceiver;
    public static final String MP4FILEPATH = "screenRecord";
    public static final String IMGFILEPATH = "screenCapture";
    private FileExportCallback mFileExportCallback;
    private AtomicBoolean mIsFileExporting = new AtomicBoolean(false);
    private AtomicBoolean mHasUDisk = new AtomicBoolean(false);  //是否有U盘
    private UDiskDevice mInUseUDiskDevice;

    /**
     * 获取文件列表
     *
     * @param type 类型 0:截图 1:录屏
     * @return
     */
    public List<FileBean> getFileList(boolean isRecording, int type) {
        String path = BaseApplication.getInstance().getDataDir().getPath() + File.separator + (type == 0 ? IMGFILEPATH : MP4FILEPATH);
        File dir = new File(path);
        List<FileBean> fileList = Collections.EMPTY_LIST;
        if (!dir.exists()) {
            boolean mkdirs = dir.mkdirs();
            Log.d(TAG, "getSavePath.mkdirs=" + mkdirs);
            return fileList;
        } else {
            fileList = getFiles(dir, type).stream().map(file -> new FileBean(false, file)).collect(Collectors.toList());
            if (isRecording && fileList.size() > 0) {  //录制中的文件不展示在列表中
                fileList.remove(fileList.size() - 1);
            }
            return fileList;
        }
    }


    /**
     * 删除后新的List数据
     *
     * @param fileList  旧的List数据
     * @param fileNames 删除的文件名集合
     * @return 新的List数据
     */
    public List<FileBean> getNewFileList(List<FileBean> fileList, List<String> fileNames) {
        return fileList.stream().filter(file -> !fileNames.contains(file.getFile().getName())).collect(Collectors.toList());
    }


    /**
     * 获取对应文件列表
     *
     * @param file 文件夹
     * @param type 类型 0:截图 1:录屏
     * @return
     */
    private List<File> getFiles(File file, int type) {
        if (file.listFiles() == null) {
            return Collections.EMPTY_LIST;
        }
        List<File> files = Arrays.asList(file.listFiles());
        return files.stream().filter(file1 -> file1.getName().endsWith(type == 0 ? ".img" : ".mp4")).sorted(Comparator.comparing(File::lastModified)).collect(Collectors.toList());
    }

    /**
     * 删除文件
     *
     * @param fileBeans 删除的文件列表
     * @return 是否删除成功
     */
    public boolean deleteFile(List<FileBean> fileBeans) {
        boolean deleteSuccess = true;
        for (FileBean file : fileBeans) {
            if (file.isChecked()) {
                File file1 = file.getFile();
                if (file1.isFile() && file1.exists()) {
                    boolean delete = file1.delete();
                    if (!delete) {
                        Log.d(TAG, "deleteFile: " + file1.getName() + " delete fail");
                        deleteSuccess = false;
                    }
                }
            }
        }
        return deleteSuccess;
    }


    /**
     * 初始化
     *
     * @param logExportCallback 回调
     */
    public void init(FileExportCallback logExportCallback) {
        this.mFileExportCallback = logExportCallback;
        mHasUDisk.set(UDiskUtil.getUDiskDeviceList().size() > 0);
        registerReceiver();
    }

    /**
     * U盘改变
     *
     * @param isAdd           添加/卸载
     * @param uDiskDeviceList 所有U盘
     */
    @Override
    public void onUsbDeviceChanged(boolean isAdd, List<UDiskDevice> uDiskDeviceList) {
        Log.d(TAG, "onUsbDeviceChanged: isAdd " + isAdd + " uDiskDeviceList = " + Arrays.toString(uDiskDeviceList.toArray()));
        mHasUDisk.set(uDiskDeviceList.size() > 0);
        if (!isAdd && isFileExporting() && mInUseUDiskDevice != null) {
            if (!uDiskDeviceList.contains(mInUseUDiskDevice)) {
                doCallbackFinishEvent(false, BaseApplication.getInstance().getString(R.string.u_disk_not_found));
            }
        }
        mFileExportCallback.onUsbChanged(isAdd, uDiskDeviceList);
    }

    /**
     * 导出完成
     *
     * @param isSucceed 是否成功
     * @param msg       提示信息
     */
    private void doCallbackFinishEvent(boolean isSucceed, String msg) {
        stop();
        mFileExportCallback.onCopyFinish(isSucceed, msg);
    }

    /**
     * 是否导出中
     */
    public boolean isFileExporting() {
        return mIsFileExporting.get();
    }

    public interface FileExportCallback {

        /**
         * 拷贝完成
         *
         * @param isSuccess 成功/失败
         * @param msg       msg
         */
        void onCopyFinish(boolean isSuccess, String msg);

        /**
         * U盘刷新
         *
         * @param isAdd           添加/删除
         * @param uDiskDeviceList U盘列表
         */
        void onUsbChanged(boolean isAdd, List<UDiskDevice> uDiskDeviceList);
    }

    /**
     * 注册U盘监听
     */
    private void registerReceiver() {
        IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
        filter.setPriority(1000);
        filter.addAction(Intent.ACTION_MEDIA_BAD_REMOVAL);
        filter.addDataScheme("file");
        mUsbReceiver = new USBReceiver(this::onUsbDeviceChanged);
        BaseApplication.getInstance().registerReceiver(mUsbReceiver, filter);
    }

    public List<UDiskDevice> getUDiskDeviceList() {
        return UDiskUtil.getUDiskDeviceList();
    }


    /**
     * 开始导出
     *
     * @param usbFile u盘
     */
    public void startZipAndOut(int type, UDiskDevice usbFile, List<FileBean> fileBeans) {
        mIsFileExporting.set(true);
        mInUseUDiskDevice = usbFile;
        StringBuffer sb = new StringBuffer();
        for (FileBean fileBean : fileBeans) {
            String filePath = fileBean.getFile().getName();
            sb.append(filePath).append(" ");
        }
        String name = new SimpleDateFormat("yyyyMMdd_HH_mm_ss", Locale.getDefault()).format(new Date());
        String uDiskPath = mInUseUDiskDevice.getPath() + File.separator + (type == 0 ? IMGFILEPATH : MP4FILEPATH) + "_" + name + ".tar.gz";
        String path = BaseApplication.getInstance().getDataDir().getPath() + File.separator + (type == 0 ? IMGFILEPATH : MP4FILEPATH);
        File dir = new File(path);
        Log.d(TAG, "start: uDiskPath=" + uDiskPath);
        int commandResult = AppUtil.runShellCommand(String.format("tar -zcf %s -C %s %s", uDiskPath, dir.getAbsolutePath(), sb.toString()));
        Log.d(TAG, "startZipAndOut: commandResult=" + commandResult);
        int sync = AppUtil.runShellCommand(String.format("sync"));
        Log.d(TAG, "startZipAndOut: sync=" + sync);
        if (commandResult == AppUtil.CODE_SUCCESS) {
            doCallbackFinishEvent(true, BaseApplication.getInstance().getString(R.string.log_out_finish));
        } else {
            doCallbackFinishEvent(false, BaseApplication.getInstance().getString(R.string.log_out_fail));
        }
    }

    /**
     * 释放
     */
    public void release() {
        if (mUsbReceiver != null) {
            BaseApplication.getInstance().unregisterReceiver(mUsbReceiver);
        }
        stop();
    }

    /**
     * 导出停止
     */
    public void stop() {
        mIsFileExporting.set(false);
        mInUseUDiskDevice = null;
    }

    public boolean hasUDisk() {
        return mHasUDisk.get();
    }


}
